package com.leyou.item.service;

import com.gitee.yongzhuzl.commonutil.util.empty.EmptyUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.vo.PageResult;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.mapper.StockMapper;
import com.leyou.item.pojo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * description: 商品相关业务
 * @author 朱正磊
 * @date 2021-04-01 18:52:41
 */
@Service
public class GoodsService {

    @Resource
    private SpuMapper spuMapper;

    @Resource
    private SpuDetailMapper spuDetailMapper;

    @Resource
    private CategoryService categoryService;

    @Resource
    private BrandService brandService;

    @Resource
    private SkuMapper skuMapper;

    @Resource
    private StockMapper stockMapper;

    @Resource
    private AmqpTemplate amqpTemplate;

    /**
     * description: 分页查询SPU
     * @author 朱正磊
     * @date 2021-04-01 19:44:41
     * @param page 当前页，如果不传默认第1页
     * @param rows 每页多少条数据，如果不传默认每页5条数据
     * @param saleable 是否上架，0下架，1上架，可以不传
     * @param key 搜索条件，可以不传
     * @return 返回SPU分页数据
     */
    public PageResult<Spu> querySpuByPage(Integer page, Integer rows, Boolean saleable, String key) {
        // 分页
        PageHelper.startPage(page, rows);

        // 过滤
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        // 根据搜索条件进行过滤
        if (EmptyUtil.isNotEmpty(key)) {
            criteria.andLike("title", "%" + key + "%");
        }
        // 根据上下架进行过滤
        if (EmptyUtil.isNotEmpty(saleable)) {
            criteria.andEqualTo("saleable", saleable);
        }

        // 默认排序
        // 这里只能写last_update_time，即必须写成数据库表字段，不可以写成实体类的属性名
        example.setOrderByClause("last_update_time desc");

        // 查询
        List<Spu> spuList = spuMapper.selectByExample(example);
        // 查询结果判断
        if (EmptyUtil.isEmpty(spuList)) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }

        // 解析商品分类名称和品牌名称
        this.resolveCategoryNameAndBrandName(spuList);

        // 解析分页结果，封装PageInfo
        PageInfo<Spu> pageInfo = new PageInfo<>(spuList);

        // 封装PageResult
        PageResult<Spu> pageResult = new PageResult<>();
        pageResult.setTotal(pageInfo.getTotal());
        pageResult.setItems(spuList);

        // 返回响应数据
        return pageResult;
    }

    /**
     * description: 解析商品分类名称和品牌名称
     * @author 朱正磊
     * @date 2021-04-01 20:40:30
     * @param spuList spu集合
     */
    private void resolveCategoryNameAndBrandName(List<Spu> spuList) {
        for (Spu spu : spuList) {
            // 处理分类名称
            List<Long> ids = Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3());
            List<Category> categoryList = categoryService.queryByIds(ids);
            List<String> names = categoryList.stream().map(Category::getName).collect(Collectors.toList());
            spu.setCname(StringUtils.join(names, "/"));

            // 处理品牌名称
            spu.setBname(brandService.queryById(spu.getBrandId()).getName());
        }
    }

    /**
     * description: 新增商品
     * @author 朱正磊
     * @date 2021-04-02 19:10:03
     * @param spu spu对象
     */
    @Transactional(rollbackFor = Throwable.class)
    public void saveGoods(Spu spu) {
        // 新增spu
        spu.setId(null);
        spu.setCreateTime(new Date());
        spu.setLastUpdateTime(spu.getCreateTime());
        // 默认有效，即逻辑未删除
        spu.setValid(true);
        // 默认上架
        spu.setSaleable(true);
        int count = spuMapper.insert(spu);
        if (count == 0) {
            throw new LyException(ExceptionEnum.GOODS_SAVE_ERROR);
        }

        // 新增spu详情
        SpuDetail spuDetail = spu.getSpuDetail();
        spuDetail.setSpuId(spu.getId());
        count = spuDetailMapper.insert(spuDetail);
        if (count == 0) {
            throw new LyException(ExceptionEnum.GOODS_SAVE_ERROR);
        }

        // 新增sku和stock库存
        this.saveSkuAndStock(spu);

        // 发送MQ消息
        amqpTemplate.convertAndSend("item.insert", spu.getId());
    }

    /**
     * description: 新增sku和stock库存
     * @author 朱正磊
     * @date 2021-04-03 21:31:06
     * @param spu spu对象
     */
    private void saveSkuAndStock(Spu spu) {
        int count;
        // 创建库存集合，方便后续批量新增库存
        List<Stock> stockList = new ArrayList<>();

        // 新增sku
        List<Sku> skus = spu.getSkus();
        for (Sku sku : skus) {
            sku.setId(null);
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(sku.getCreateTime());
            sku.setSpuId(spu.getId());
            count = skuMapper.insert(sku);
            if (count == 0) {
                throw new LyException(ExceptionEnum.GOODS_SAVE_ERROR);
            }

            // 获取库存
            Stock stock = new Stock();
            stock.setSkuId(sku.getId());
            stock.setStock(sku.getStock());
            stockList.add(stock);
        }

        // 批量新增库存
        count = stockMapper.insertList(stockList);
        if (count == 0) {
            throw new LyException(ExceptionEnum.GOODS_SAVE_ERROR);
        }
    }

    /**
     * description: 根据spu的id查询spu详情
     * @author 朱正磊
     * @date 2021-04-03 15:23:45
     * @param spuId spu的id
     * @return 返回spu详情
     */
    public SpuDetail queryDetailById(Long spuId) {
        SpuDetail spuDetail = spuDetailMapper.selectByPrimaryKey(spuId);
        if (EmptyUtil.isEmpty(spuDetail)) {
            throw new LyException(ExceptionEnum.GOODS_DETAIL_NOT_FOUND);
        }
        return spuDetail;
    }

    /**
     * description: 根据spu的id查询sku集合
     * @author 朱正磊
     * @date 2021-04-03 15:40:19
     * @param spuId spu的id
     * @return 返回sku集合
     */
    public List<Sku> querySkuListBySpuId(Long spuId) {
        // 查询sku
        Sku sku = new Sku();
        sku.setSpuId(spuId);
        List<Sku> skuList = skuMapper.select(sku);
        if (EmptyUtil.isEmpty(skuList)) {
            throw new LyException(ExceptionEnum.GOODS_SKU_NOT_FOUND);
        }

        // 查询库存
        // 获取skuId集合
        List<Long> skuIdList = skuList.stream().map(Sku::getId).collect(Collectors.toList());
        // 根据skuId集合批量查询库存对象集合（库存表的主键就是skuId）
        List<Stock> stockList = stockMapper.selectByIdList(skuIdList);
        if (EmptyUtil.isEmpty(stockList)) {
            throw new LyException(ExceptionEnum.GOODS_STOCK_NOT_FOUND);
        }
        // 将库存对象集合转换成Map对象，key是skuId，value是库存值
        Map<Long, Integer> stockMap = stockList.stream().collect(Collectors.toMap(Stock::getSkuId, Stock::getStock));
        // 给sku设置库存
        skuList.forEach(e -> e.setStock(stockMap.get(e.getId())));

        // 返回查询结果
        return skuList;
    }

    /**
     * description: 修改商品
     * @author 朱正磊
     * @date 2021-04-03 18:19:42
     * @param spu spu对象
     */
    @Transactional(rollbackFor = Throwable.class)
    public void updateGoods(Spu spu) {
        if (EmptyUtil.isEmpty(spu.getId())) {
            throw new LyException(ExceptionEnum.GOODS_ID_CANNOT_BE_NULL);
        }

        // 删除sku和stock库存
        Sku sku = new Sku();
        sku.setSpuId(spu.getId());
        List<Sku> skuList = skuMapper.select(sku);
        if (EmptyUtil.isNotEmpty(skuList)) {
            List<Long> skuIdList = skuList.stream().map(Sku::getId).collect(Collectors.toList());
            // 批量删除sku（也可以使用：skuMapper.delete(sku)来进行批量删除，即根据spuId进行批量删除）
            skuMapper.deleteByIdList(skuIdList);
            // 批量删除stock
            stockMapper.deleteByIdList(skuIdList);
        }

        // 修改spu
        spu.setSaleable(null);
        spu.setValid(null);
        spu.setCreateTime(null);
        spu.setLastUpdateTime(new Date());
        // 非空更新
        int count = spuMapper.updateByPrimaryKeySelective(spu);
        if (count == 0) {
            throw new LyException(ExceptionEnum.GOODS_UPDATE_ERROR);
        }

        // 修改商品详情即spu detail
        count = spuDetailMapper.updateByPrimaryKeySelective(spu.getSpuDetail());
        if (count == 0) {
            throw new LyException(ExceptionEnum.GOODS_UPDATE_ERROR);
        }

        // 新增sku和stock库存
        this.saveSkuAndStock(spu);

        // 发送MQ消息
        amqpTemplate.convertAndSend("item.update", spu.getId());
    }

    /**
     * description: 根据spu的id查询spu包括skus以及spuDetail
     * @author 朱正磊
     * @date 2021-04-12 00:05:13
     * @param id spu的id
     * @return 返回spu包括skus以及spuDetail
     */
    public Spu querySpuById(Long id) {
        // 查询spu
        Spu spu = spuMapper.selectByPrimaryKey(id);
        if (EmptyUtil.isEmpty(spu)) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        // 查询skus
        spu.setSkus(this.querySkuListBySpuId(id));
        // 查询spu详情
        spu.setSpuDetail(this.queryDetailById(id));
        // 返回spu
        return spu;
    }

}
